package com.pet.item.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pet.common.domain.Result;
import com.pet.item.domain.po.Item;
import com.pet.item.domain.po.ItemDoc;
import com.pet.item.mapper.ItemMapper;
import com.pet.item.service.ISearchService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * es 服务实现类
 * </p>
 *
 * @author Cookies
 * @since 2025-01-13
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SearchServiceImpl extends ServiceImpl<ItemMapper, Item> implements ISearchService {
    private RestHighLevelClient client;

    @Override
    public Result searchItem(String keyword) {
        SearchRequest request = new SearchRequest("items");
        request.source()
                .query(
                        QueryBuilders.matchQuery("name", keyword)
                )
                .highlighter(
                        SearchSourceBuilder.highlight()
                                .field("name")
                                .preTags("<hl>")
                                .postTags("</hl>")
                );
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = response.getHits().getHits();
            List<ItemDoc> items = new ArrayList<>();
            for (SearchHit hit : hits) {
                String json = hit.getSourceAsString();
                ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                if (CollUtil.isNotEmpty(highlightFields)) {
                    HighlightField highlightField = highlightFields.get("name");
                    if (highlightField != null) {
                        String hfName = highlightField.getFragments()[0].string();
                        itemDoc.setName(hfName);
                    }
                    items.add(itemDoc);
                }
            }
            return Result.success(items);
        } catch (IOException e) {
            log.error(e.getMessage());
            return Result.error("服务繁忙，请稍后再试~");
        }
    }

    @PostConstruct
    private void setUp() {
        System.out.println("setUp 启动了...");
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.47.101:9200")
        ));
    }

    @PreDestroy
    private void tearDown() {
        System.out.println("tearDown 关闭了...");
        if (this.client != null) {
            try {
                this.client.close();
            } catch (Exception e) {
                log.error("Failed to close Elasticsearch client", e);
            }
        }
    }
}
